package com.bluesky.jwf.component.tree;

import com.bluesky.javawebbrowser.domain.html.tags.Tag;
import com.bluesky.jwf.ComponentFactory;
import com.bluesky.jwf.component.Component;
import com.bluesky.jwf.component.HyperLinkButton;
import com.bluesky.jwf.component.event.AbstractEventHandler;
import com.bluesky.jwf.component.event.EventHandler;
import com.bluesky.jwf.component.list.ListItem;

/**
 * it represents a row of the tree view.
 * 
 * @author hz00260
 * 
 */
public class TreeViewItem extends ListItem {

	public static String EVENT_TOGGLE_EXPAND = "toggle-expand";

	protected boolean expanded;

	protected Tag listTag;

	protected Tag blankTag;
	protected Tag lineTag;

	protected Tag expandedTag;
	protected Tag collapsedTag;
	protected Tag leafTag;

	protected Tag lastExpandedTag;
	protected Tag lastCollapsedTag;
	protected Tag lastLeafTag;

	protected Tag contentTag;

	protected HyperLinkButton expandBtn;
	protected HyperLinkButton collapseBtn;
	protected HyperLinkButton lastExpandBtn;
	protected HyperLinkButton lastCollapseBtn;

	public TreeViewItem() {
		expanded = false;
	}

	@Override
	public void init(String html) {

		super.init(html);

		listTag = loadByJwfClass("list");

		blankTag = listTag.loadByJwfClass("blank");
		lineTag = listTag.loadByJwfClass("line");

		expandedTag = listTag.loadByJwfClass("expanded");
		collapsedTag = listTag.loadByJwfClass("collapsed");
		leafTag = listTag.loadByJwfClass("leaf");
		lastExpandedTag = listTag.loadByJwfClass("last-expanded");
		lastCollapsedTag = listTag.loadByJwfClass("last-collapsed");
		lastLeafTag = listTag.loadByJwfClass("last-leaf");

		contentTag = listTag.loadByJwfClass("content");

		EventHandler expandHandler = new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				TreeView tv = (TreeView) getListView();
				tv.expand((TreeViewItem) target
						.getAncesterByClass(TreeViewItem.class));

			}
		};
		EventHandler collapseHandler = new AbstractEventHandler() {
			@Override
			public void handle(Component target, Object parameter) {
				TreeView tv = (TreeView) getListView();
				tv.collapse((TreeViewItem) target
						.getAncesterByClass(TreeViewItem.class));

			}
		};

		Tag expandLinkTag = collapsedTag.loadByJwfClass("link");
		expandBtn = (HyperLinkButton) ComponentFactory.getInstance()
				.createComponent(HyperLinkButton.class.getSimpleName(),
						expandLinkTag.toHtml());
		expandLinkTag.replace(expandBtn);
		expandBtn.setClickHandler(expandHandler);

		Tag lastExpandLinkTag = lastCollapsedTag.loadByJwfClass("link");
		lastExpandBtn = (HyperLinkButton) ComponentFactory.getInstance()
				.createComponent(HyperLinkButton.class.getSimpleName(),
						lastExpandLinkTag.toHtml());
		lastExpandLinkTag.replace(lastExpandBtn);
		lastExpandBtn.setClickHandler(expandHandler);

		Tag collapseLinkTag = expandedTag.loadByJwfClass("link");
		collapseBtn = (HyperLinkButton) ComponentFactory.getInstance()
				.createComponent(HyperLinkButton.class.getSimpleName(),
						collapseLinkTag.toHtml());
		collapseLinkTag.replace(collapseBtn);
		collapseBtn.setClickHandler(collapseHandler);

		Tag lastCollapseLinkTag = lastExpandedTag.loadByJwfClass("link");
		lastCollapseBtn = (HyperLinkButton) ComponentFactory.getInstance()
				.createComponent(HyperLinkButton.class.getSimpleName(),
						lastCollapseLinkTag.toHtml());
		lastCollapseLinkTag.replace(lastCollapseBtn);
		lastCollapseBtn.setClickHandler(collapseHandler);
	}

	@Override
	public void updateView() {
		TreeView tv = (TreeView) listView;
		TreeNodeNavigator ng = tv.getNavigator();

		listTag.removeAllChildren();

		for (int i = ng.getDepth(model); i > 0; i--) {
			Object ancestor = ng.getAncester(model, i);
			if (ng.isLastChild(ancestor))
				listTag.addChild(blankTag.clone());
			else
				listTag.addChild(lineTag.clone());
		}

		// is leaf
		if (ng.getChildren(model) == null || ng.getChildren(model).isEmpty()) {
			if (ng.isLastChild(model))
				listTag.addChild(lastLeafTag);
			else
				listTag.addChild(leafTag);
		} else {
			if (expanded) {
				if (ng.isLastChild(model))
					listTag.addChild(lastExpandedTag);
				else
					listTag.addChild(expandedTag);
			} else {
				if (ng.isLastChild(model))
					listTag.addChild(lastCollapsedTag);
				else
					listTag.addChild(collapsedTag);
			}
		}
		listTag.addChild(contentTag);
	}

	public boolean isExpanded() {
		return expanded;
	}

	public void setExpanded(boolean expanded) {
		this.expanded = expanded;
	}

}
